﻿#pragma once
#include <QObject>
#include <QScopedPointer>
#include <QPointer>
#include <QList>

class ObjectSelector : public QObject {
    Q_OBJECT
    struct ObjectSelectorData;
    QScopedPointer<ObjectSelectorData> d;

public:
    enum ObjectSelectFlag {
        NoUpdate = 0x0000,
        Clear = 0x0001,
        Select = 0x0002,
        Deselect = 0x0004,
        Toggle = 0x0008,
        Current = 0x0010,
        SelectCurrent = Select | Current,
        ToggleCurrent = Toggle | Current,
        ClearAndSelect = Clear | Select
    };
    Q_DECLARE_FLAGS(ObjectSelectFlags, ObjectSelectFlag)

public:
    explicit ObjectSelector(QObject *parent = nullptr);
    virtual ~ObjectSelector();
    static QPointer<ObjectSelector> instance();
    void excludeObject(QPointer<QObject> object);

public slots:
    void select(QPointer<QObject> object, ObjectSelectFlags command = ObjectSelectFlag::Current);
    void setCurrentObject(QPointer<QObject> object);
    void clearCurrentObject();
    QPointer<QObject> currentObject() const;
    void setEnabled(bool enable);

signals:
    void currentChanged(QPointer<QObject> current, const QPointer<QObject> previous);
    void selectionChanged(const QList<QPointer<QObject>> selected, const QList<QPointer<QObject>> deselected);

protected:
    bool eventFilter(QObject *watched, QEvent *event) override;

private slots:
    void onCurrentChanged(QPointer<QObject> current, const QPointer<QObject> previous);
    void onSelectionChanged(const QList<QPointer<QObject>> selected, const QList<QPointer<QObject>> deselected);
};

Q_DECLARE_OPERATORS_FOR_FLAGS(ObjectSelector::ObjectSelectFlags)
